package cn.longwingstech.intelligence.bibackend.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.RandomUtil;
import cn.longwingstech.intelligence.bibackend.model.vo.user.LoginUserVO;
import cn.longwingstech.intelligence.bibackend.model.vo.user.UserVO;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import cn.longwingstech.intelligence.bibackend.model.entity.User;
import cn.longwingstech.intelligence.bibackend.mapper.UserMapper;
import cn.longwingstech.intelligence.bibackend.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.time.LocalDateTime;

/**
 * 用户 服务层实现。
 *
 * @author 君墨
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>  implements UserService{

    /**
     * 用户注册
     *
     * @param userAccount
     * @param userPassword
     * @param checkPassword
     * @return
     */
    @Override
    public Long userRegister(String userAccount, String userPassword, String checkPassword) {
        // 断言
        Assert.hasText(userAccount, "用户账户不能为空");
        Assert.hasText(userPassword, "用户密码不能为空");
        Assert.hasText(checkPassword, "确认密码不能为空");
        Assert.state(userPassword.equals(checkPassword), "两次输入的密码不一致");
        Assert.state(userPassword.length() >= 8, "用户密码过短");
        // 验证用户是否唯一
        QueryWrapper queryWrapper = QueryWrapper.create().eq(User::getUserAccount, userAccount);
        long count = this.mapper.selectCountByQuery(queryWrapper);
        Assert.state(count == 0, "用户已存在");
        // 密码加密
        String password = SaSecureUtil.sha256(userPassword);
        User user = new User();
        user.setUserAccount(userAccount);
        user.setUserPassword(password);
        user.setUserRole("user");
        user.setUserName("user_" + RandomUtil.randomString(6));
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        int result = this.mapper.insert(user);
        Assert.state(result > 0, "用户注册失败");
        return user.getId();
    }

    /**
     * 用户登录
     *
     * @param userAccount
     * @param userPassword
     * @return
     */
    @Override
    public LoginUserVO userLogin(String userAccount, String userPassword) {
        Assert.hasText(userAccount, "用户账户不能为空");
        Assert.hasText(userPassword, "用户密码不能为空");
        String password = SaSecureUtil.sha256(userPassword);
        QueryWrapper queryWrapper = QueryWrapper.create().eq(User::getUserAccount, userAccount).eq(User::getUserPassword, password);
        User user = this.mapper.selectOneByQuery(queryWrapper);
        Assert.state(user != null, "用户不存在或密码错误");

        StpUtil.login(user.getId());
        StpUtil.getSession().set("user", user);

        String tokenValue = StpUtil.getTokenValue();
        LoginUserVO loginUserVO = getLoginUserVO(user);
        loginUserVO.setToken(tokenValue);

        return loginUserVO;
    }

    /**
     * 用户注销
     *
     * @return
     */
    @Override
    public Boolean userLogout() {
        StpUtil.logout();
        return true;
    }

    /**
     * 获取当前登录用户
     *
     * @return
     */
    @Override
    public User getLoginUser() {
        return  StpUtil.getSession().getModel("user",User.class);
    }

    /**
     * 获取当前用户 (脱敏)
     *
     * @param user
     * @return
     */
    @Override
    public LoginUserVO getLoginUserVO(User user) {
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtils.copyProperties(user, loginUserVO);
        return loginUserVO;
    }

    /**
     * 获取用户 (脱敏)
     *
     * @param user
     * @return
     */
    @Override
    public UserVO getUserVO(User user) {
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }
}
